﻿namespace PasswordStrengthener
{
    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Linq;
    using System.Security.Cryptography;
    using System.Text;
    using System.Windows;

    public static class Worker
    {
        private static readonly int Ops;
        private static readonly SHA512 Sha512 = new SHA512Managed();

        static Worker()
        {
            byte[] bytes = new byte[50];
            new Random().NextBytes(bytes);

            Stopwatch sw = Stopwatch.StartNew();
            const int N = 10 * 1000;

            for (int i = 0; i < N; i++)
            {
                bytes = Hash(bytes);
            }

            sw.Stop();

            Ops = N * 1000 / (int)sw.ElapsedMilliseconds;
        }

        private static byte[] Hash(byte[] bytes)
        {
            return Sha512.ComputeHash(bytes);
        }

        public static byte[] Hash(byte[] bytes, long iterations, Action<int> percentCallback = null)
        {
            long itersPerPercent = iterations / 100;
            bool callbackExists = percentCallback != null;

            for (long i = 0; i < iterations; i++)
            {
                bytes = Hash(bytes);
                if (callbackExists && i % itersPerPercent == 0)
                {
                    percentCallback((int)(i / itersPerPercent));
                }
            }
            return bytes;
        }

        public static string Hash(string s, long iterations, Action<int> percentCallback = null)
        {
            return Convert.ToBase64String(
                Hash(Encoding.ASCII.GetBytes(s), iterations, percentCallback)).
                Replace("+", string.Empty).
                Replace("/", string.Empty).
                Replace("=", string.Empty);
        }

        public static TimeSpan GetTime(long iterations)
        {
            return TimeSpan.FromSeconds(1d * iterations / Ops);
        }
    }
}
